package com.cloud.xtools.common.util;

import jakarta.servlet.http.HttpServletRequest;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Component;

/**
 * @author Daixinguo
 */
@Component
public class Auth {

    // ThreadLocal 是 Java 提供的一个类，用于在多线程环境下为每个线程维护独立的变量副本。这意味着每个线程都可以独立地更改其 ThreadLocal 变量的值，而不会影响其他线程的变量副本。ThreadLocal 通常用于在不通过参数传递的情况下，为每个线程存储和访问线程本地的数据。
    // 以下是 ThreadLocal 的一些关键特性和用法：
    // #关键特性
    // -线程隔离：每个线程都有自己的 ThreadLocal 变量副本，因此一个线程对 ThreadLocal 变量的修改不会影响其他线程。
    // -内存泄漏风险：如果 ThreadLocal 变量没有被正确清理，可能会导致内存泄漏，尤其是在使用线程池的情况下。
    // -适用场景：适用于需要在同一个线程的不同方法之间共享数据，但又不想通过方法参数显式传递的情况。
    // #常用方法
    // set(T value)：设置当前线程的 ThreadLocal 变量的值。
    // get()：获取当前线程的 ThreadLocal 变量的值。
    // remove()：移除当前线程的 ThreadLocal 变量的值，有助于防止内存泄漏。

    private static final ThreadLocal<HttpServletRequest> REQUEST_HOLDER = new ThreadLocal<>();

    // 通过 AuthInterceptor 拦截器将请求对象保存到 ThreadLocal 中
    public static void setRequest(HttpServletRequest request) {
        REQUEST_HOLDER.set(request);
    }

    public static void clearRequest() {
        REQUEST_HOLDER.remove();
    }

    public static HttpServletRequest getRequest() {
        return REQUEST_HOLDER.get();
    }

    // 获取用户ID
    @Nullable
    public static Long getUserId() {
        HttpServletRequest request = getRequest();
        if (request != null) {
            Object userId = request.getAttribute("user_id");
            if (userId instanceof Integer) {
                return ((Integer) userId).longValue();
            } else {
                return null;
            }
        }
        return null;
    }

    // 获取用户名
    @Nullable
    public static String getUsername() {
        HttpServletRequest request = getRequest();
        if (request != null) {
            Object username = request.getAttribute("username");
            if (username instanceof String) {
                return (String) username;
            } else {
                return null;
            }
        }
        return null;
    }
}
